package com.sugon.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.lang.Assert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.sugon.dao.*;
import com.sugon.entity.SparePartEntity;
import com.sugon.entity.SparePartSafeStockEntity;
import com.sugon.entity.SysDeptEntity;
import com.sugon.entity.vo.SparePartSafeStockNewlyAddParam;
import com.sugon.modules.sparepart.consts.SparePartSafeStockState;
import com.sugon.service.SparePartSafeStockService;
import com.sugon.utils.Constant;
import com.sugon.utils.ShiroUtils;
import com.sugon.utils.excel.ExcelImport;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 各车间备件安全库存配置Service实现类
 *
 * @author YuXD
 * @date 2022-07-04
 */
@Service("sparePartSafeStockService")
public class SparePartSafeStockServiceImpl implements SparePartSafeStockService {

    @Resource
    private SparePartSafeStockDao safeStockDao;
    @Resource
    private SparePartRequDetailDao requDetailDao;
    @Resource
    private SpareStorePosDao spareStorePosDao;
    @Resource
    private SparePartDao sparePartDao;
    @Resource
    private SysDeptDao deptDao;

    @Override
    public SparePartSafeStockEntity queryObject(String id) {
        return safeStockDao.queryObject(id);
    }

    @Override
    public List<SparePartSafeStockEntity> queryList(Map<String, Object> map) {
        return safeStockDao.queryList(map);
    }

    @Override
    public boolean configDeptSafeStock(SparePartSafeStockNewlyAddParam newlyAddParam) {
        SparePartSafeStockEntity safeStock = new SparePartSafeStockEntity();
        // 复制备件ID、车间安全库存数
        BeanUtil.copyProperties(newlyAddParam, safeStock);
        safeStock.setDeptId(ShiroUtils.getWorkshop());
        // 手动添加的都是未审批
        safeStock.setState(SparePartSafeStockState.NEW);
        int saveNum = save(safeStock);
        Assert.isTrue(saveNum > 0);
        // 需要计算需求数和在途数
        recomputeSparePartDemandNum(safeStock.getSparePartId());
        return true;
    }

    /**
     * 更新备件需求数
     *
     * @param sparePartId
     */
    private void recomputeSparePartDemandNum(String sparePartId) {
        /*
            需求数量=安全库存-库存-在途；
            各车间出现同一备件时，进行统一运算，并全部进行提醒，安全库存=各车间安全库存的和
         */
        // 安全库存
        int totalSafeStock = safeStockDao.sumSafeStock(sparePartId);
        // 统计总库存数
        int totalStockNum = spareStorePosDao.sumStockNum(sparePartId);
        // 备件总在途数
        int transitNum = requDetailDao.sumTransitNum(null, CollectionUtil.newArrayList(sparePartId));
        // 需求数不得小于0
        int demandNum = totalSafeStock - totalStockNum - transitNum;
        safeStockDao.updateDemandNum(sparePartId, demandNum < 0 ? 0 : demandNum);
    }

    @Override
    public List<SparePartSafeStockEntity> queryList(String deptId, String sparePartId) {
        Map<String, Object> queryParam = MapUtil.newHashMap();
        queryParam.put("deptId", deptId);
        queryParam.put("sparePartId", sparePartId);
        return queryList(queryParam);
    }

    @Override
    public int queryTotal(Map<String, Object> map) {
        return safeStockDao.queryTotal(map);
    }

    @Override
    public int save(SparePartSafeStockEntity sparePartSafeStock) {
        sparePartSafeStock.setId(RandomUtil.randomString(32));
        sparePartSafeStock.setCreateDate(DateUtil.date());
        sparePartSafeStock.setCreateUser(ShiroUtils.getUserId());
        sparePartSafeStock.setDelFlag(Constant.IS_NOT_DEL_INT);
        return safeStockDao.save(sparePartSafeStock);
    }

    @Override
    public int update(SparePartSafeStockEntity sparePartSafeStock) {
        sparePartSafeStock.setGmtModified(DateUtil.date());
        sparePartSafeStock.setUpdateUser(ShiroUtils.getUserId());
        int updateFlag = safeStockDao.update(sparePartSafeStock);
        Assert.isTrue(updateFlag == 1);
        // 重新计算下数目
        recomputeSparePartDemandNum(sparePartSafeStock.getSparePartId());
        return updateFlag;
    }

    @Override
    public int delete(String id) {
        return safeStockDao.delete(id);
    }

    @Override
    public int deleteBatch(String[] ids) {
        // 先查询匹配的备件安全库存列表
        List<SparePartSafeStockEntity> safeStockList = safeStockDao.selectByIds(ids);
        // 删除后
        int deleteBatchNum = safeStockDao.deleteBatch(ids);
        if (deleteBatchNum > 0) {
            if (CollectionUtil.isNotEmpty(safeStockList)) {
                List<String> idList = safeStockList.stream().map(SparePartSafeStockEntity::getSparePartId).distinct().collect(Collectors.toList());
                for (String sparePartId : idList) {
                    recomputeSparePartDemandNum(sparePartId);
                }
            }
        }
        return deleteBatchNum;
    }


    @Override
    public int importE(MultipartFile file) {
        List<String[]> list = ExcelImport.getExcelData(file);
        int count = 0;
        if (CollectionUtil.isNotEmpty(list)) {
            String deptId, spareCode;
            SparePartEntity sp;
            SparePartSafeStockEntity safeStock;
            Set<String> spareIdSet = new HashSet<>();
            for (int i = 1; i < list.size(); i++) {
                String[] array = list.get(i);
                // 必要数据非空校验
                if (!StrUtil.isAllNotEmpty(array[0], array[1], array[5], array[6])) {
                    continue;
                }
                // 校验车间名称是否合法
                List<SysDeptEntity> deptList = deptDao.queryByName(array[0]);
                if (CollectionUtil.isEmpty(deptList)) {
                    continue;
                }
                deptId = deptList.get(0).getDeptId();
                // 校验备件编码是否合法
                spareCode = array[1];
                sp = sparePartDao.queryByCode(spareCode);
                if (sp == null) {
                    continue;
                }
                boolean isSave = true;
                // 校验是否已关联过
                List<SparePartSafeStockEntity> safeStockList = safeStockDao.query(deptId, sp.getId());
                if (CollectionUtil.isNotEmpty(safeStockList)) {
                    isSave = false;
                    safeStock = safeStockList.get(0);
                } else {
                    safeStock = new SparePartSafeStockEntity();
                    safeStock.setDeptId(deptId);
                    safeStock.setSparePartId(sp.getId());
                }
                safeStock.setSafeNum(NumberUtil.parseInt(array[5]));
                // 导入的默认设置为已审核通过
                safeStock.setState(SparePartSafeStockState.PASSED);
                spareIdSet.add(safeStock.getSparePartId());
                count += isSave ? save(safeStock) : onlyUpdate(safeStock);
            }
            // 需要计算需求数和在途数
            for (String spareId : spareIdSet) {
                recomputeSparePartDemandNum(spareId);
            }
        }
        return count;
    }

    private int onlyUpdate(SparePartSafeStockEntity sparePartSafeStock) {
        sparePartSafeStock.setGmtModified(DateUtil.date());
        sparePartSafeStock.setUpdateUser(ShiroUtils.getUserId());
        int updateFlag = safeStockDao.update(sparePartSafeStock);
        Assert.isTrue(updateFlag == 1);
        return updateFlag;
    }

}
